
#import "CBLECenterMnger.h"
#import "CBLEDataMsg.h"
#import "BleUUIDDefine.h"
#import "RHCustomTimer.h"
#import "RHBleCmdManager.h"

#define CONNECT_TIMEOUT 30  //连接超时

@interface CBLECenterMnger()
@property(nonatomic,strong)NSMutableArray*       waitSendMsgList;
@property(nonatomic,assign)NSInteger             msgLastType;
@property(nonatomic,strong)CBCentralManager*     centerMnager;
@property(nonatomic,assign)NSInteger             reConnectIdx;    //蓝牙重新断开后，重新连接的次数
@property (nonatomic ,copy) NSString *localPheralIdentifer;  //要连接的本地设备,使用mac地址
@property (nonatomic ,strong) NSTimer *connectTimer; //连接设备定时器
@property (nonatomic ,assign) NSInteger connectCount;//连接的时间秒数

@end


@implementation CBLECenterMnger

+ (BOOL)BLEIsPowerOff{
    BOOL isPowerOff = (![CBLECenterMnger shareMnger].bIsPowerOn)||([CBLECenterMnger shareMnger].centerMnager.state == CBManagerStateUnauthorized);
    return isPowerOff;
}

+ (nullable CBLECenterMnger *)shareMnger{
    
    static dispatch_once_t pred = 0;
    __strong static CBLECenterMnger   *_bleMnger = nil;
    dispatch_once(&pred, ^{
        _bleMnger = [[self alloc] init];
    });
    return _bleMnger;
}

-(instancetype)init{
    if ( self = [super init] ){
        _centerMnager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
        _dataPherals  = [CDataPheralMnger dataMnger];
        [self resetDefaultData];
    }
    return self;
}

+ (void)checkAuthState:(void(^)(CBManagerState))authBlock
{
    [CBLECenterMnger shareMnger].authBlock = authBlock;
    CBManagerState state = [CBLECenterMnger shareMnger].centerMnager.state;
    //首次初始化实例的时候状态是 CBManagerStateUnknown;
    if(state == CBManagerStatePoweredOn){
        authBlock(state);
    }
    if(state == CBManagerStatePoweredOff){
        QMUIAlertController *alertVC = [QMUIAlertController alertControllerWithTitle:@"提示".rh_localized message:@"请前往手机-->设置-->蓝牙,打开蓝牙开关".rh_localized preferredStyle:QMUIAlertControllerStyleAlert];
        QMUIAlertAction *sure = [QMUIAlertAction actionWithTitle:@"确定".rh_localized style:QMUIAlertActionStyleDefault handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
            
        }];
        [alertVC addAction:sure];
        [alertVC showWithAnimated:YES];
    }
    if(state == CBManagerStateUnauthorized){
        QMUIAlertController *alertVC = [QMUIAlertController alertControllerWithTitle:@"提示".rh_localized message:@"请前往手机-->设置-->隐私-->蓝牙,打开app蓝牙开关".rh_localized preferredStyle:QMUIAlertControllerStyleAlert];
        QMUIAlertAction *sure = [QMUIAlertAction actionWithTitle:@"确定".rh_localized style:QMUIAlertActionStyleDefault handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
            
        }];
        [alertVC addAction:sure];
        [alertVC showWithAnimated:YES];
    }
    NSLog(@"------->查询蓝牙授权状态:%ld",[CBLECenterMnger shareMnger].centerMnager.state);
}


-(void)resetDefaultData{
    _reConnectIdx  = 0;
    _bIsPowerOn    = NO;
    [_dataPherals removeAll];
    _curPheral = nil;
}


- (void)cmdStopScan{
    [_centerMnager stopScan];
    
}

- (void)scanANCSPheriacl{
    
    NSString *strSericeID = SERVICE_UUID;
    CBUUID   *uuid = [CBUUID UUIDWithString:strSericeID];
    
    //UUID是外设的服务UUID，满足UUID 的外设就会放在数组中
    __weak __typeof(&*self)weakSelf = self;
    NSArray *arr = [_centerMnager retrieveConnectedPeripheralsWithServices:@[uuid]];
    if ( arr != nil && arr.count > 0 ){
        [arr enumerateObjectsUsingBlock:^(CBPeripheral *obj, NSUInteger idx, BOOL *stop) {
            [weakSelf centralManager:_centerMnager didDiscoverPeripheral:obj advertisementData:nil RSSI:[NSNumber numberWithInt:0]];
            //NSLog(@"连接=====%@ %lu   /n%@",obj,(unsigned long)idx,obj.services);
            //        [self discoverANCS:obj];
        }];
    } else {
        NSLog(@".....retrieveConnectedPeripheralsWithServices没有返回任何已连接的设备！");
    }

}

- (void)cmdStartScan{

    if (_curPheral != nil ) {
        NSLog(@"---->扫描前断开连接的设备:%@",_curPheral.devName);
        [_centerMnager cancelPeripheralConnection:_curPheral.peripheral];
        _curPheral = nil;
    }
    [self.dataPherals removeAll];
    //[self scanANCSPheriacl];
    //[NSThread sleepForTimeInterval:2];
    //[_centerMnager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:SERVICE_UUID]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:NO]}];
    
    //@[[CBUUID UUIDWithString:SERVICE_UUID]]
    NSLog(@"---->扫描设备");
    [_centerMnager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:YES]}];
}

- (void)cmdDisconnectCurPheral{
    self.isManualDisconnect = YES;
    NSLog(@"111---->断开当前连接的蓝牙设备:%@",_curPheral.devName);
    if ( _curPheral == nil ) return;
    NSLog(@"222---->断开当前连接的蓝牙设备:%@",_curPheral.devName);
    [_centerMnager cancelPeripheralConnection:_curPheral.peripheral];
    _curPheral = nil;
}


- (void)cmdConnect2Pheral:(CDataPheralInfo*)pheral{
    if ( pheral == nil ) return;
    [QMUITips hideAllTips];
    [ProgressHUDManage showLoading:@"连接设备...".rh_localized];
    [self startConnectTimer];
    NSLog(@"--连接设备--：%@",pheral);
    NSLog(@"---->设备状态:%ld",pheral.peripheral.state);
    
    _curPheral = pheral;
    if(pheral.peripheral.state == CBPeripheralStateConnected){
      
        POST_MESSAGE(BLEMSG_PHERAL_CONNECT_RST);
        
    }else{
        [_centerMnager connectPeripheral:pheral.peripheral options:nil];
    }
    
}

#pragma mark ----- 连接本地保存的设备 -----
- (void)connectLocalPeripheral:(CDataPheralInfo*)pheral
{
    [ProgressHUDManage showLoading:@"连接设备...".rh_localized];
    [self startConnectTimer];
    self.localPheralIdentifer = pheral.devName;
    if([CBLECenterMnger shareMnger].bIsPowerOn){
        [[CBLECenterMnger shareMnger] cmdStartScan];
    }
}

-(void)startConnectTimer
{
    self.connectCount = 0;
    if (self.connectTimer==nil) {
        self.connectTimer = [RHCustomTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(connectingCount) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop]addTimer:self.connectTimer forMode:NSRunLoopCommonModes];
    }
}

-(void)stopConnectTimer
{
    [self.connectTimer invalidate];
    self.connectTimer = nil;
    self.connectCount = 0;
}

-(void)connectingCount
{
    if(self.connectCount == CONNECT_TIMEOUT){
        [QMUITips hideAllTips];
        self.localPheralIdentifer = nil;
        [ProgressHUDManage showInfo:@"连接超时".rh_localized];
        [self cmdDisconnectCurPheral];
        [self stopConnectTimer];
        return;
    }
    self.connectCount ++;
    NSLog(@"----->连接设备......%ld",self.connectCount);
}


- (BOOL)isScaning{
    return [_centerMnager isScanning];
}

- (BOOL)isCanScan{
    if ( _bIsPowerOn && _curPheral == nil )
        return YES;
    return FALSE;
}

- (BOOL)isConnectOK{
    if ( _curPheral != nil &&
        CBPeripheralStateConnected == _curPheral.peripheral.state )
        return YES;
    return NO;
}

-(void)logicCBPowerOn:(BOOL)bIsPowerOn{
    
    //蓝牙中心设备状态改变，通知界面给出提示
    _bIsPowerOn = bIsPowerOn;
    //连接本地设备
    if(bIsPowerOn && self.localPheralIdentifer){
        NSLog(@"---->连接本地设备")
        [self cmdStartScan];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:BLEMSG_CENTER_POWERON object:nil];
}

//
// 蓝牙中心代理
//
#pragma mark 【1】监测蓝牙状态
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    switch (central.state){
        case CBManagerStateUnknown:      break;
        case CBManagerStateResetting:    break;
        case CBManagerStateUnsupported:  break;
        case CBManagerStateUnauthorized:
        {
            QMUIAlertController *alertVC = [QMUIAlertController alertControllerWithTitle:@"提示".rh_localized message:@"请前往手机-->设置-->隐私-->蓝牙,打开app蓝牙开关".rh_localized preferredStyle:QMUIAlertControllerStyleAlert];
            QMUIAlertAction *sure = [QMUIAlertAction actionWithTitle:@"确定".rh_localized style:QMUIAlertActionStyleDefault handler:^(__kindof QMUIAlertController * _Nonnull aAlertController, QMUIAlertAction * _Nonnull action) {
                
            }];
            [alertVC addAction:sure];
            [alertVC showWithAnimated:YES];
            break;
        }
            
        case CBManagerStatePoweredOff: 
        {
            [self logicCBPowerOn:NO];
           //系统会弹窗
            break;
        }
        
        case CBManagerStatePoweredOn:
        {
            [self logicCBPowerOn:YES];
            break;
        }
    }
    NSLog(@"------->授权状态发生改变:%ld",central.state);
}

#pragma mark 【2】发现外部蓝牙设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    NSString *localName = advertisementData[@"kCBAdvDataLocalName"];
    if(localName.length == 0){
        localName = peripheral.name;
    }
    
    if (localName.length < 2) return;
    NSString *filter = [localName substringToIndex:2];
    if ([filter containsString:@"K0"]||
        [filter containsString:@"K2"]||
        [filter containsString:@"R0"]||
        [filter containsString:@"R2"]||
        [filter containsString:@"Z0"]||
        [filter containsString:@"Z2"]||
        [filter containsString:@"RD"]) {
        
    }else{
        return;
    }
    NSLog(@"发现新的蓝牙设备:%@ peripheral.name=%@ kCBAdvDataLocalName=%@  %@ %@",RSSI,peripheral.name,localName,peripheral.identifier.UUIDString,advertisementData);
    CDataPheralInfo *data = [CDataPheralInfo dataPheral:peripheral advData:advertisementData RSSI:RSSI];
    
    //360k
    if ([filter containsString:@"K0"]||
        [filter containsString:@"R0"]||
        [filter containsString:@"Z0"]||
        [filter containsString:@"RD"]) {
        data.wifiType = DevWiFiType360K;
    }
    
    //362k
    if ([filter containsString:@"K2"]||[filter containsString:@"R2"]||[filter containsString:@"Z2"]) {
        //第一个广播数据没有厂家数据,过滤掉   360的没有厂家数据,不用过滤
        if(!advertisementData[@"kCBAdvDataManufacturerData"])return;
        data.wifiType = DevWiFiType362K;
    }
    //品牌
    if ([filter containsString:@"R0"]||[filter containsString:@"R2"]||[filter containsString:@"RD"]) {
        data.brandType = DevBrandTypeRenon;
    }
    if ([filter containsString:@"K0"]||[filter containsString:@"K2"]) {
        data.brandType = DevBrandTypeKowint;
    }
    if ([filter containsString:@"Z0"]||[filter containsString:@"Z2"]) {
        data.brandType = DevBrandTypeZRGP;
    }
    
    data.devName = [localName substringFromIndex:2];
    //连接本地设备
    if([data.devName isEqualToString:self.localPheralIdentifer]){
        NSLog(@"---->发现本地设备,准备连接:%@",self.localPheralIdentifer);
        [self cmdStopScan];
        [self cmdConnect2Pheral:data];
    }
    
    BOOL isAdd = [self.dataPherals addPheral:data];
    //只有新发现的蓝牙才通知UI
    if ( isAdd ){
        [[NSNotificationCenter defaultCenter] postNotificationName:BLEMSG_CENTER_NEWPHERAL object:data];
    }
}

#pragma mark 【3】连接外部蓝牙设备成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"------>连接蓝牙成功:%@",peripheral.identifier.UUIDString);
    [self stopConnectTimer];
    [[RHBleCmdManager shareMnger] startHeartTimer];
    if(self.localPheralIdentifer){
        [SVProgressHUD dismiss];
        self.localPheralIdentifer = nil;
    }
    self.isManualDisconnect = NO;
    _reConnectIdx = 0;
    NSLog(@"----->扫描服务");
    [_curPheral startFindSrv:peripheral];
    [self performSelector:@selector(contentSuccessNotic) withObject:nil afterDelay:1.0];
    
    //连接蓝牙成功以后，查询BOOTLOAD版本
    //JW**[self performSelector:@selector(checkBootVerInAppMode) withObject:nil afterDelay:3.0];
}

#pragma mark 【4】连接外部蓝牙设备失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
  
    [self stopConnectTimer];
    NSLog(@"---->连接失败:%@",error);
    
    //连接蓝牙失败，通知界面做逻辑处理
    if(self.localPheralIdentifer){
        [SVProgressHUD dismiss];
        self.localPheralIdentifer = nil;
    }
    _curPheral = nil;
    POST_MESSAGE(BLEMSG_PHERAL_CONNECT_RST);
}

#pragma mark 【5】蓝牙外设连接断开，自动重连
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    [[RHBleCmdManager shareMnger] stopHeartTimer];
    if(self.isManualDisconnect == NO){
        [QMUITips hideAllTips];
        [ProgressHUDManage showInfo:@"设备已断开".rh_localized];
    }
    
    NSLog(@"------>蓝牙已断开:%@  %@",peripheral.name,peripheral.identifier.UUIDString);
    if(error){
        NSLog(@"----->错误信息:%@",error);
    }
    POST_MSG_WITHOBJ(BLEMSG_PHERAL_DISCONNECT,peripheral);
    //重连
    if(self.isManualDisconnect == NO){
        NSLog(@"----->重连设备");
        [self cmdConnect2Pheral:_curPheral];
    }else{
        _curPheral = nil;
    }
    
#if 0
    //1.停止发送所有指令
    
    //2.通知界面
    _reConnectIdx ++;
    NSString *strTryNum = [NSString stringWithFormat:@"%ld",(long)_reConnectIdx];
    POST_MSG_WITHOBJ(BLEMSG_PHERAL_DISCONNECT,strTryNum);
    if ( peripheral && _reConnectIdx < BLE_CONST_MAX_TRYCONNECT ) {
        _reConnectIdx++;
        NSLog(@"\n\n断开与%@的连接，正在尝试第[%ld]次重连...\n\n",_curPheral.peripheral,(long)_reConnectIdx);
        [self cmdConnect2Pheral:_curPheral bConnect:YES];
    }
#endif
}


-(void)checkBootVerInAppMode{
    if ( !self.curPheral.bIsInOTA ){
        [self appCmdVersion];
    }
}

- (void)contentSuccessNotic{
    [QMUITips hideAllTips];
    [ProgressHUDManage hideTips];
    POST_MESSAGE(BLEMSG_PHERAL_CONNECT_RST);
}

@end




////////////////////////////////////////////////////////////////////////////////
/*
 *       CBLECenterMnger BLEWrist command with ack
 */
////////////////////////////////////////////////////////////////////////////////
@implementation CBLECenterMnger (BLEWristCmd)
- (void)wristSendCmdAckMsg:(NSData*)data{
    
    if ( _curPheral != nil ){
        [_curPheral writeCmdAckMsg:data];
    } else {
        NSLog(@"------>当前没有连接蓝牙，不能发送wrist命令!");
    }
}

-(void)wristWriteOTACmd:(NSData*)data bInOTA:(BOOL)bInOTA{
 
    if ( _curPheral != nil ){
        [_curPheral writeOTACmd:data bInOTA:bInOTA];
    } else {
        NSLog(@"------>当前没有连接蓝牙，不能发送OTA命令!");
    }
}

-(void)wristWriteOTAData:(NSData*)data{
    
    if ( _curPheral != nil ){
        [_curPheral writeOTAData:data];
    } else {
        NSLog(@"------>当前没有连接蓝牙，不能发送OTA数据!");
    }
}

- (void)wristWriteData:(NSData*)data{
   
    if ( _curPheral != nil ){
        [_curPheral writeCmdAckMsg:data];
    } else {
        [ProgressHUDManage showInfo:@"蓝牙已断开!".rh_localized];
        NSLog(@"------>当前没有连接蓝牙，不能发送指令!");
    }
}

- (void)wristReadData:(NSData*)data{
    if ( _curPheral != nil ){
        [_curPheral readCmdAckMsg:data];
    } else {
        [ProgressHUDManage showInfo:@"蓝牙已断开!".rh_localized];
        NSLog(@"------>当前没有连接蓝牙，不能发送指令!");
    }
}


- (BOOL)wristSsidMsg:(NSData*)data{
    if ( _curPheral != nil ){
        return [_curPheral wristSsidMsg:data];
    } else {
        NSLog(@"------>当前没有连接蓝牙，不能发送指令!");
        return NO;
    }
}

- (BOOL)wristPassMsg:(NSData*)data{
    if ( _curPheral != nil ){
        return  [_curPheral wristPassMsg:data];
    } else {
        NSLog(@"------>当前没有连接蓝牙，不能发送指令!");
        return NO;
    }
}

- (void)wristCmdSetLED:(NSUInteger)nChannel nVal:(NSUInteger)nVal{
    NSData *cmdData = [CBLEDataMsg buildLEDMsg:nChannel nVal:nVal];
    [self wristSendCmdAckMsg:cmdData];
}

- (void)wristCmdStartSensor:(BOOL)bStart{
    NSData *cmdData = [CBLEDataMsg buildStartSensorMsg:bStart];
    [self wristSendCmdAckMsg:cmdData];
}


- (void)wristCmdStartHR:(BOOL)bStart{
    NSData *cmdData = [CBLEDataMsg buildStartHeartRate:bStart];
    [self wristSendCmdAckMsg:cmdData];
}

- (void)wristNotifyNewMsg:(NSUInteger)nMsgType{
    NSData *cmdData = [CBLEDataMsg buildNewMsgNotify:nMsgType strMsg:nil  moreState:WristMsgFlagBrief];
    [self wristSendCmdAckMsg:cmdData];
}

- (void)wristSendMsg:(NSString*)strSummary strMsg:(NSString*)strMsg msgType:(NSUInteger)msgType{
    
    self.msgLastType = msgType;
    NSInteger moreState = WristMsgFlagBrief;
    
    if ( strMsg != nil && strMsg.length > 0 ){
        moreState = WristMsgFlagBriefText;
        //在此将消息正文转换为数组
        self.waitSendMsgList = [CBLEDataMsg convertMsg2Ary:strMsg];
    }
    
    NSData *cmdData = [CBLEDataMsg buildNewMsgNotify:msgType strMsg:strSummary  moreState:moreState];
    [self wristSendCmdAckMsg:cmdData];
}

//发送剩余的正文消息
- (void)wristSendMsgMore{
    
    NSInteger nNums = self.waitSendMsgList.count;
    if ( nNums <= 0 ) return;
    
    NSString *strMsg = [self.waitSendMsgList firstObject];
    if ( strMsg == nil || strMsg.length <= 0 )
        return;
    
    [self.waitSendMsgList removeObjectAtIndex:0];
    NSInteger moreState = WristMsgFlagTextMore;
    if ( nNums == 1 )
        moreState = WristMsgFlagTextLast;
    
    NSData *cmdData = [CBLEDataMsg buildNewMsgNotify:self.msgLastType  strMsg:strMsg  moreState:moreState];
    [self wristSendCmdAckMsg:cmdData];
    
}

- (void)wristSendMsgByWeChat:(NSString*)strBrief strMsg:(NSString*)strMsg{
    [self wristSendMsg:strBrief strMsg:strMsg msgType:BLEWristSendMsgTypeNewWeChat];
}

- (void)wristSendMsgBySMS:(NSString*)strBrief strMsg:(NSString*)strMsg{
   [self wristSendMsg:strBrief strMsg:strMsg msgType:BLEWristSendMsgTypeNewSMS];
}

@end



////////////////////////////////////////////////////////////////////////////////
/*
 *       CBLECenterMnger BLEWrist OTACmd for app
 */
////////////////////////////////////////////////////////////////////////////////

@implementation CBLECenterMnger (BLEWristOTACmdInApp)

-(void)appCmdSwitch2OTA{
    NSLog(@"appCmdSwitch2OTA==");
    NSData *cmdData = [CBLEDataMsg buildApp2OTA];
    [self wristWriteOTACmd:cmdData bInOTA:NO];
    
}

-(void)appCmdSwitch2OTARes{
    NSLog(@"appCmdSwitch2OTARes==");
    NSData *cmdData = [CBLEDataMsg buildApp2OTARes];
    [self wristWriteOTACmd:cmdData bInOTA:NO];
    
}

-(void)appCmdVersion{
    NSLog(@"appCmdVersion==");
    NSData *cmdData = [CBLEDataMsg buildBleVersion];
    [self wristWriteOTACmd:cmdData bInOTA:NO];
}

@end



////////////////////////////////////////////////////////////////////////////////
/*
 *       CBLECenterMnger BLEWrist command for OTA mode
 */
////////////////////////////////////////////////////////////////////////////////


@implementation CBLECenterMnger (BLEWristOTACmdInOTA)
-(void)otaCmd2App{
    NSLog(@"otaCmd2App===");
    NSData *cmdData = [CBLEDataMsg buildOTA2App];
    [self wristWriteOTACmd:cmdData bInOTA:YES];
    //POST_MSG_WITHOBJ(BLEMSG_PHERAL_DISCONNECT,0);
}

-(void)otaCmsStart:(NSInteger)nPartitionNums{
    NSLog(@"otaCmsStart===");
    NSData *cmdData = [CBLEDataMsg buildOTAStart:nPartitionNums];
    [self wristWriteOTACmd:cmdData bInOTA:YES];
}

-(void)otaCmdByData:(NSData*)cmdData{
    
}
@end
